use solutiont2::BatchTable;
use std::collections::BTreeSet;
use std::ops::BitAnd;

pub fn count_provinces() -> String {
    // let path = "topic1/solutiont2/district.json";
    // let path = "district.json";
    // let data = read_json_data(path);
    let data = compile_time_read_json_data();
    let mut res = String::with_capacity(data.len() * 2 - 1);
    for (index, dis) in data.0.into_iter() {
        let mut tmp: Vec<Option<BTreeSet<String>>> = Vec::with_capacity(dis.len());
        for (key, mut value) in dis.0.into_iter() {
            value.insert(key);
            tmp.push(Some(value.into_iter().collect()));
        }
        for i in 0..tmp.len() - 1 {
            if tmp[i].is_none() {
                continue;
            }
            for j in i + 1..tmp.len() {
                if tmp[j].is_none() {
                    continue;
                }
                if tmp[i]
                    .as_ref()
                    .unwrap()
                    .bitand(tmp[j].as_ref().unwrap())
                    .len()
                    != 0
                {
                    let tmp_value = tmp[j].take().unwrap();
                    tmp[i].as_mut().unwrap().extend(tmp_value);
                }
            }
        }
        let res_set = tmp.into_iter().filter(|x| x.is_some()).collect::<Vec<_>>();
        match index {
            1 => res.extend([res_set.len().to_string().as_str()]),
            _ => res.extend([",", res_set.len().to_string().as_str()]),
        }
    }
    res
}

// /// 读取json数据
// #[inline(always)]
// fn read_json_data(path: &str) -> BatchTable {
//     let file = std::fs::File::open(path).unwrap();
//     let reader = std::io::BufReader::new(file);
//     let data: BatchTable = serde_json::from_reader(reader).unwrap();
//     data
// }

/// 编译期内嵌 json 数据减少运行时 `IO` 开销
#[inline(always)]
fn compile_time_read_json_data() -> BatchTable {
    let json = include_str!("../district.json");
    let data: BatchTable = serde_json::from_str(json).unwrap();
    data
}

// /// `HashMap + HashSet` 方案 => 弃用
// pub fn count_provinces() -> String {
//     let path = "district.json";
//     let path = "topic1/solutiont2/district.json";
//     let data = read_json_data(path);
//     let mut res = String::with_capacity(data.len());
//     for (index, dis) in data.0.into_iter() {
//         let mut tmp: HashMap<String, HashSet<String>> = HashMap::with_capacity(dis.len());
//         for (key, value) in dis.0.into_iter() {
//             for v in value.iter() {
//                 tmp.entry(v.clone()).or_default();
//             }
//             tmp.entry(key).or_default().extend(value);
//         }
//         let mut tmp_key: Vec<String> = tmp.keys().map(|x| x.clone()).collect();
//         tmp_key.sort_by_key(|x| tmp[x].len());
//         tmp_key.reverse();
//         let mut tmp_map: HashMap<usize, usize> = HashMap::with_capacity(tmp.len());
//         for (i, step) in tmp_key.iter().enumerate() {
//             let mut key: Vec<String> = tmp.keys().map(|x| x.clone()).collect();
//             key.sort_by_key(|x| tmp[x].len());
//             key.reverse();
//             println!("{:?} {}", key, step);
//             if !tmp.contains_key(step) {
//                 continue;
//             }
//             for (j, k) in tmp_key.iter().enumerate() {
//                 if tmp.contains_key(k) && step != k && tmp[step].contains(k) {
//                     let tmp_value = tmp.remove(k).unwrap();
//                     tmp.get_mut(step).unwrap().extend(tmp_value);
//                     tmp_map.insert(j, i);
//                 }
//             }
//             for (k, v) in tmp_map.iter_mut() {
//                 if tmp.contains_key(&tmp_key[*v]) && step != &tmp_key[*v] && tmp[step].contains(&tmp_key[*k]) {
//                     let tmp_value = tmp.remove(&tmp_key[*v]).unwrap();
//                     tmp.get_mut(step).unwrap().extend(tmp_value);
//                     *v = i;
//                 }
//             }
//         }
//         println!("{:#?}", tmp);
//         match index {
//             1 => res.extend([tmp.len().to_string().as_str()]),
//             _ => res.extend([",", tmp.len().to_string().as_str()])
//         }
//     }
//     res
// }
